﻿using System.Windows.Controls;

namespace devMobile.Controls.Status
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;

    public partial class SignalAccuracyControl : UserControl, ISignalAccuracyControl, INotifyPropertyChanged, IRangeBehaviour
    {

        private const int _signalHeight = 4;

        private const int _totalSignalas = 6;

        private readonly int _totalHeight = _totalSignalas * _signalHeight;

        private int _relativeHeight;

        private int _maxValue = 100;

        private int _value;

        private List<RangeBehaviourItem> _rangeBehaviourCollection = new List<RangeBehaviourItem>();

        public SignalAccuracyControl()
        {
            InitializeComponent();
        }

        private void SetVisibilityLevel(int rectangle, int height)
        {
            //Contract.Requires(height > 0, "height must be greater than zero");
            height = height < 0 ? 0 : height;
            height = height > 4 ? 4 : height;

            ((Rectangle)this.LayoutRoot.FindName(string.Format("s{0}", rectangle))).Height = height;
        }

        private void SetFillBrush(Brush brush)
        {
            for (int i = 1; i <= _totalSignalas; i++)
            {
                ((Rectangle)this.LayoutRoot.FindName(string.Format("s{0}", i))).Fill = brush;
            }
        }

        public void Draw()
        {
            var aux = _relativeHeight;
            for (int i = 1; i <= _totalSignalas; i++)
            {
                if (aux > i * _signalHeight)
                {
                    SetVisibilityLevel(i, _signalHeight);
                }
                else
                {
                    SetVisibilityLevel(i, aux);
                }
                aux -= _signalHeight;
            }
        }

        public Brush SignalColor
        {
            set
            {
                this.SetFillBrush(value);
            }
        }

        public int MaxValue
        {
            get
            {
                return _maxValue;
            }
            set
            {
                _maxValue = value;
            }
        }

        public int Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
                NotifyPropertyChanged("Value");
                this._relativeHeight = (this.Value * _totalHeight) / this._maxValue;
                Dispatcher.BeginInvoke(
                    () =>
                        {
                            this.Draw();
                            ApplyBehaviour();
                        });

            }
        }

        public void ApplyBehaviour(bool animationWhenNoSignal = true)
        {
            this.ApplyBehaviour(animationWhenNoSignal, this._rangeBehaviourCollection);
        }

        public void ApplyBehaviour(bool animationWhenNoSignal, List<RangeBehaviourItem> rangeBehaviours)
        {
            RangeBehaviourCollection = rangeBehaviours;
            foreach (var rangeBehaviour in _rangeBehaviourCollection)
            {
                if ((this.Value >= rangeBehaviour.FromValue) && (this.Value <= rangeBehaviour.ToValue))
                {
                    this.SignalColor = rangeBehaviour.SignalColor;
                    if (animationWhenNoSignal && (this.Value <= 5))
                    {
                        if (MinAnimation.GetCurrentState() == ClockState.Stopped)
                        {
                            MinAnimation.Begin();
                            MinAnimation.RepeatBehavior = new RepeatBehavior(TimeSpan.FromSeconds(10.0));
                        }
                        this.SetVisibilityLevel(1, 4);
                    }
                    else
                    {
                        MinAnimation.Stop();
                    }
                }
            }
        }

        public IEnumerable<RangeBehaviourItem> RangeBehaviourCollection
        {
            get
            {
                return _rangeBehaviourCollection;
            }
            set
            {
                _rangeBehaviourCollection = (List<RangeBehaviourItem>)value;
                NotifyPropertyChanged("RangeBehaviourCollection");
            }
        }

        public Orientation Orientation
        {
            set 
            {
                LayoutRoot.RenderTransform = new RotateTransform { Angle = (double)value };
                NotifyPropertyChanged("Orientation");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
